/*
 * @Author: January
 * @Date: 2022-01-03 20:23:08
 */

#ifndef __AES_H__
#define __AES_H__
#include <libecc/lib_ecc_config.h>
#include <libecc/words/words.h>

# ifdef  __cplusplus
extern "C" {
# endif

# define AES_ENCRYPT     1
# define AES_DECRYPT     0
/*
 * Because array size can't be a const in C, the following two are macros.
 * Both sizes are in bytes.
 */
# define AES_MAXNR 14
# define AES_BLOCK_SIZE 16

/* This should be a hidden type, but EVP requires that the size be known */
typedef struct aes_key_st {
# ifdef AES_LONG
    unsigned long rd_key[4 * (AES_MAXNR + 1)];
# else
    unsigned int rd_key[4 * (AES_MAXNR + 1)];
# endif
    int rounds;
} AES_KEY;


int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
                        AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
                        AES_KEY *key);

void AES_encrypt( const AES_KEY *key, const unsigned char *in,
                  unsigned char *out);
void AES_decrypt( const AES_KEY *key, const unsigned char *in,
                  unsigned char *out);

typedef struct {
    u8 nonce[AES_BLOCK_SIZE];
    AES_KEY rk;
} aes_context;

int aes_encrypt_init(aes_context* ctx, const u8* iv, int iv_len, const u8* key, int key_len);

int aes_decrypt_init(aes_context* ctx, const u8* iv, int iv_len, const u8* key, int key_len);

void aes_encrypt_cbc(aes_context* ctx, const u8* in, int in_len, u8* out);

void aes_decrypt_cbc(aes_context* ctx, const u8* in, int in_len, u8* out);

void aes_process_ctr(aes_context* ctx, const u8* in, int in_len, u8* out);

void aes_finalize(aes_context* ctx);

# ifdef  __cplusplus
}
# endif

#endif